package com.mapbar.ure;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 基于java的regex的通用模式匹配。
 * 
 * @author QIN Jian
 * 
 * @param <T>
 *            用户定义类型
 */
public class WrapRE<T> {

	Pattern pattern;
	private HashMap<T, Character> map;

	/**
	 * 构造函数
	 * 
	 * @param pattern
	 *            待编译的模式。
	 * @param map
	 *            用户定义类型与Character的对应关系，以用于向String的转换。
	 */
	public WrapRE(List<T> pattern, HashMap<T, Character> map) {
		StringBuilder sb = new StringBuilder();
		for (T t : pattern) {
			sb.append(map.get(t));
		}
		this.pattern = Pattern.compile(sb.toString());
		this.map = map;
	}

	/**
	 * 进行匹配
	 * 
	 * @param input
	 *            待匹配的输入
	 * @return 返回 {@link Matcher}
	 */
	public Matcher match(List<T> input) {
		StringBuilder sb = new StringBuilder();
		for (T t : input) {
			sb.append(map.get(t));
		}
		return pattern.matcher(sb.toString());
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		charDemo();
		System.out.println("charDemo() finished.");
		intDemo();
		System.out.println("intDemo() finished.");
	}

	private static void charDemo() {
		/**
		 * 以下为各项准备
		 */
		HashMap<Character, Character> map = new HashMap<Character, Character>();
		map.put('(', '(');
		map.put(')', ')');
		map.put('+', '+');
		map.put('*', '*');
		map.put('|', '|');
		map.put('0', '0');
		map.put('1', '1');
		map.put('2', '2');
		map.put('3', '3');
		map.put('4', '4');
		map.put('5', '5');
		map.put('6', '6');
		map.put('7', '7');
		map.put('8', '8');
		map.put('9', '9');
		map.put('.', '.');

		List<Character> pattern = new ArrayList<Character>();
		String input = "(0|1|2|3|4|5|6|7|8|9).(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)";
		input = "(1|2|3).(2|3)*45";
		for (char c : input.toCharArray()) {
			pattern.add(c);
		}

		WrapRE<Character> ure = new WrapRE<Character>(pattern, map);

		/**
		 * 以下为匹配测试。
		 */
		String ss[] = new String[] { "0.12", "1.232333245", "3.12", "32.12" };
		for (String s : ss) {
			System.out.println("==================");
			System.out.print("匹配：");
			List<Character> i = new ArrayList<Character>();
			for (char c : s.toCharArray()) {
				i.add(c);
			}
			for (Character c : s.toCharArray()) {
				System.out.print(" " + c);
			}
			System.out.print('\n');
			Matcher m = ure.match(i);
			if (m.matches()) {
				System.out.println("匹配成功。");
			} else {
				System.out.println("匹配失败。");
			}
		}
		System.out.println("==================");

	}

	private static void intDemo() {
		HashMap<Integer, Character> map = new HashMap<Integer, Character>();
		map.put(-1, '(');
		map.put(-2, ')');
		map.put(-4, '*');
		map.put(-5, '|');
		map.put(0, 'a');
		map.put(1, 'b');
		map.put(2, 'c');
		map.put(3, 'd');
		map.put(4, 'e');
		map.put(5, 'f');
		map.put(6, 'h');
		map.put(7, 'i');
		map.put(8, 'j');
		map.put(9, 'k');

		List<Integer> pattern = new ArrayList<Integer>();
		Integer[] in = { 0, 1, 8, 9, -1, 0, -5, 2, -5, 4, -2 };
		for (Integer i : in) {
			pattern.add(i);
		}
		WrapRE<Integer> ure = new WrapRE<>(pattern, map);

		/**
		 * 以下为匹配测试。
		 */
		Integer ss[][] = new Integer[][] { { 0, 1, 8, 9, 4 }, { 1, 1 },
				{ 9, 4 }, { 0, 1, 8, 9, 0 }, { 0, 1, 8, 9, 5 } };
		for (Integer[] s : ss) {
			System.out.println("==================");
			System.out.print("匹配：");
			for (Integer i : s) {
				System.out.print(" " + i);
			}
			System.out.print('\n');
			List<Integer> i = new ArrayList<Integer>();
			for (Integer c : s) {
				i.add(c);
			}

			Matcher m = ure.match(i);
			if (m.matches()) {
				System.out.println("匹配成功。");
			} else {
				System.out.println("匹配失败。");
			}
		}
		System.out.println("==================");
	}
}
